home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr47 / asmlib40.zip / FLOAT.DOC < prev    next >
Text File  |  1995-01-25  |  23KB  |  866 lines

  1.  
  2. ***********************  FLOATING-POINT DATA  *******************************
  3.  
  4. ASMLIB floating-point data subroutines (C) Copyright 1991 - 1995 Douglas Herr
  5. all rights reserved
  6.  
  7. ASMLIB recognizes two floating point formats: IEEE-standard single-
  8. precision, and IEEE-standard double-precision.  Single-precision
  9. floating point numbers are 4 bytes long, and are referred to as float4
  10. or simply f4, while double-precision floating point numbers are 8 bytes
  11. long, which I describe as float8 or f8.
  12.  
  13.  
  14.  
  15. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  16.  
  17. ABSF4:     absolute value of float4 number
  18. Source:    absf4.asm
  19.  
  20. Call with: DS:[BX] pointing to 4-byte real number
  21. Returns:   number converted to absolute value
  22. Uses:      flags
  23.  
  24. Example:
  25.  
  26. include asm.inc
  27.  
  28. extrn   absf4:proc
  29.  
  30. .data
  31. f4      dd -123.456
  32.  
  33. .code
  34.         .
  35.         .
  36.         .
  37.         lea     bx,f4            ; point to 4-byte real number
  38.         call    absf4            ; convert to absolute value
  39.  
  40.  
  41. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  42.  
  43. ABSF8:     absolute value of float8 number
  44. Source:    absf8.asm
  45.  
  46. Call with: DS:[BX] pointing to 8-byte real number
  47. Returns:   number converted to absolute value
  48. Uses:      flags
  49.  
  50. Example:
  51.  
  52. include asm.inc
  53.  
  54. extrn   absf8:proc
  55.  
  56. .data
  57. f8      dq -123.456789
  58.  
  59. .code
  60.         .
  61.         .
  62.         .
  63.         lea     bx,f8            ; point to 8-byte real number
  64.         call    absf8            ; convert to absolute value
  65.  
  66.  
  67. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  68.  
  69. ADDF4:     add two float4 numbers
  70. Source:    addf4.asm
  71.  
  72. 80x87 not required
  73.  
  74. Call with: DS:[SI] pointing to real0, ES:[DI] pointing to real1
  75.            both numbers must be single-precision rel numbers in IEEE format
  76. Returns:   if CF = 0, real0 is replaced by the sum
  77.            if CF = 1, the sum would result in an overflow; neither
  78.            number is changed
  79. Uses:      CF
  80.  
  81. Example:
  82.  
  83. include asm.inc
  84.  
  85. extrn addf4:proc
  86.  
  87. .data
  88. real0   dd 123.456
  89. real1   dd -67.4
  90.  
  91. .code
  92. ; program fragment assumes DS:@data
  93.          .
  94.          .
  95.          .
  96.         push    ds
  97.         pop     es           ; ES = DS
  98.         assume  es:@data
  99.         lea     si,real0
  100.         lea     di,real1
  101.         call    addf4
  102.  
  103. ; note that this can be used for subtraction by changing the sign
  104. ; of one of the numbers
  105. ;
  106. ; changing the sign is trivial: if DS:[SI] points to a float4 number,
  107. ; the sign is changed with
  108. ;
  109. ;      xor    byte ptr 3[si],10000000b
  110.  
  111.  
  112. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  113.  
  114. ADDF8:     add two float8 numbers
  115. Source:    addf8.asm
  116.  
  117. 80x87 not required
  118.  
  119. Call with: DS:[SI] pointing to real0, ES:[DI] pointing to real1
  120.            both number must be double-precision real numbers in IEEE format
  121. Returns:   if CF = 0, real0 is replaced by the sum
  122.            if CF = 1, the sum would result in an overflow; neither
  123.            number is changed
  124. Uses:      CF
  125.  
  126. Example:
  127.  
  128. include asm.inc
  129.  
  130. extrn addf8:proc
  131.  
  132. .data
  133.  
  134. real0   dq 123.456
  135. real1   dq -67.4
  136.  
  137. .code
  138. ; program fragment assumes DS:@data
  139.          .
  140.          .
  141.          .
  142.         push    ds
  143.         pop     es           ; ES = DS
  144.         assume  es:@data
  145.         lea     si,real0
  146.         lea     di,real1
  147.         call    addf8
  148.  
  149. ; note that this can be used for subtraction by changing the sign
  150. ; of one of the numbers
  151. ;
  152. ; changing the sign is trivial: if DS:[SI] points to a float8 number,
  153. ; the sign is changed with
  154. ;
  155. ;      xor    byte ptr 7[si],10000000b
  156.  
  157.  
  158.  
  159. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  160.  
  161. CMPF4:      compare two float4 numbers
  162. Source:     cmpf4.asm
  163.  
  164. CMPF8:      compare two float8 numbers
  165. Source:     cmpf8.asm
  166.  
  167. 80x87 NOT required
  168.  
  169. Call with:  DS:[SI] pointing to number 0
  170.             ES:[DI] pointing to number 1
  171. Returns:    if ZF = 1, numbers are equal
  172.             if SF = 1, number 1 is larger
  173. Uses:       zero flag (ZF), sign flag (SF)
  174. Example:
  175.  
  176. include  asm.inc
  177.  
  178. extrn    cmpf4:proc
  179.  
  180. .data
  181. v0       dd 12.345
  182. v1       dd 17.04
  183.  
  184. .code
  185. ; program fragment assumes DS:@data
  186.          .
  187.          .
  188.          .
  189.          push   ds
  190.          pop    es               ; in this example, both numbers are in DGROUP
  191.          assume es:@data
  192.          lea    si,v0            ; point DS:[SI] to number 0
  193.          lea    di,v1            ; point ES:[DI] to number 1
  194.          call   cmpf4            ; compare
  195.          js     real1           ; number 1 is larger if SF = 1
  196.          je     equal            ; both float4 numbers are identical if ZF = 1
  197.                                  ; otherwise number 0 is larger
  198.  
  199.  
  200. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  201.  
  202. DIVI2:      divides integer in AX by integer in DX, returning float4 quotient
  203. Source:     divi2.asm (i2tof4.asm, invf4.asm, mulf4.asm)
  204.  
  205. 80x87 not required
  206.  
  207. Call with:  AX, DX = I2 numbers; DX <> 0
  208.             DS:[BX] pointing to 4-byte buffer for quotient
  209.             DivI2 does not check for divide-by-zero errors
  210.             make sure DX <> 0 and you'll be OK
  211. Returns:    quotient at DS:[BX], f4 format
  212. Uses:       nothing; all flags and registers are saved
  213. Example:
  214.  
  215. include asm.inc
  216.  
  217. extrn   divi2:proc
  218.  
  219. .data
  220. f4data  dd ?                     ; 4 bytes for resulting quotient
  221.  
  222. .code
  223. ; program fragment assumes DS:@data
  224.         .
  225.         .
  226.         .
  227.         mov    ax,17             ; I want to calculate 17/47
  228.         mov    dx,47             ; don't ask me why
  229.         lea    bx,f4data         ; point to 4-byte data area
  230.         call   divi2
  231.  
  232.  
  233. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  234.  
  235. F4TOF8:     converts a float4 number to float8 format
  236. Source:     f4tof8.asm
  237.  
  238. 80x87 not required
  239.  
  240. Call with:  DS:[SI] pointing to float4 number
  241.             ES:[DI] pointing to 8-byte buffer for float8 number
  242. Returns:    CF = 0 if successful
  243.             CF = 1 if the float4 number is invalid
  244. Uses:       CF; all other flags and registers are saved
  245. Example:
  246.  
  247. include asm.inc
  248.  
  249. extrn  f4tof8:proc
  250.  
  251. .data
  252. float4      dd 123.456
  253. float8      dq ?
  254.  
  255. .code
  256. ; program fragment assumes DS:@data
  257.              .
  258.              .
  259.              .
  260.             push    ds
  261.             pop     es           ; ES = DS
  262.             assume  es:@data
  263.             lea     si,float4           ; DS:[SI] points to float4 number
  264.             lea     di,float8           ; ES:[DI] points to float8 buffer
  265.             call    f4tof8
  266.             jc      oops                ; go to error handler if problem
  267.  
  268.  
  269.  
  270.  
  271. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  272.  
  273. F4TOI2:     copies the integer portion of a float4 number to AX
  274. Source:     f4toi2.asm
  275.  
  276. 80x87 not required
  277.  
  278. Note:       only the integer portion of the number is converted; decimals
  279.             are truncated
  280. Call with:  DS:[SI] pointing to a float4 number
  281. Returns:    if CF = 0, AX = integer number
  282.             if CF = 1, float4 number is too large (if positive)
  283.                        or is too small (if negtive)
  284. Uses:       AX, CF; all other flags and registers are saved
  285. Example:
  286.  
  287. include asm.inc
  288.  
  289. extrn   f4toi2:proc
  290.  
  291. .data
  292. float4  dd  1234.567
  293.  
  294. .code
  295. ; program fragment assumes DS:@data
  296.         .
  297.         .
  298.         .
  299.         lea  si,float4
  300.         call f4toi2
  301.         jc   oops                     ; gotta fix something if error
  302.  
  303.  
  304.  
  305. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  306.  
  307. F4TOI4:     copies the long integer portion of a float4 number to DX:AX
  308. Source:     f4toi4.asm
  309.  
  310. 80x87 not required
  311.  
  312. Note:       only the integer portion of the number is converted; decimals
  313.             are truncated
  314. Call with:  DS:[SI] pointing to a float4 number
  315. Returns:    if CF = 0, DX:AX = long integer number
  316.             if CF = 1, float4 number is too large (if positive)
  317.                        or is too small (if negtive)
  318. Uses:       AX, DX, CF; all other flags and registers are saved
  319. Example:
  320.  
  321. include asm.inc
  322.  
  323. extrn   f4toi4:proc
  324.  
  325. .data
  326. float4  dd  1234.567
  327.  
  328. .code
  329. ; program fragment assumes DS:@data
  330.         .
  331.         .
  332.         .
  333.         lea    si,float4
  334.         call   f4toi4
  335.         jc     oops                   ; gotta fix something if error
  336.  
  337.  
  338.  
  339.  
  340. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  341.  
  342. F8TOF4:     converts a float8 number to float4 format
  343. Source:     f8tof4.asm
  344.  
  345. 80x87 not required
  346.  
  347. Call with:  DS:[SI] pointing to float8 number
  348.             ES:[DI] pointing to 4-byte buffer for float4 number
  349. Returns:    CF = 0 if no error
  350.             CF = 1 float8 number overflowed to infinity
  351.                    or underflowed to zero
  352. Uses:       CF; all other flags and registers are saved
  353. Example:
  354.  
  355. include asm.inc
  356.  
  357. extrn  f8tof4:proc
  358.  
  359. .data
  360. float8      dq 123.456
  361. float4      dd ?
  362.  
  363. .code
  364. ; program fragment assumes DS:@data
  365.              .
  366.              .
  367.              .
  368.             push    ds
  369.             pop     es           ; ES = DS
  370.             assume  es:@data
  371.             lea     si,float8           ; DS:[SI] points to float8 number
  372.             lea     di,float4           ; ES:[DI] points to float4 buffer
  373.             call    f8tof4
  374.             jc      oops                ; go to error handler if problem
  375.  
  376.  
  377.  
  378.  
  379. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  380.  
  381. I2TOF4:     convert integer number to float4 IEEE format
  382. Source:     i2tof4.asm
  383.  
  384. 80x87 not required
  385.  
  386. Call with:  DS:[BX] pointing to 4-byte buffer for float4 number
  387.             AX = signed integer number to convert
  388. Returns:    converted number in float4 IEEE format at DS:[BX]
  389. Uses:       nothing; all registers and flags are saved
  390. Example:
  391.  
  392. include asm.inc
  393.  
  394. extrn   i2tof4:proc
  395.  
  396. .data
  397. float4  dd ?                   ; initial number undefined
  398.  
  399. .code
  400. ; program fragment assumes DS:@data
  401.         .
  402.         .
  403.         .
  404.         mov    ax,12345        ; signed integer number in AX
  405.         lea    bx,float4       ; this is where I want the resulting number
  406.         call   i2tof4
  407.  
  408.  
  409.  
  410. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  411.  
  412. I4TOF4:     convert long integer number to float4 IEEE format
  413. Source:     i4tof4.asm
  414.  
  415. 80x87 not required
  416.  
  417. Call with:  DS:[BX] pointing to 4-byte buffer for float4 number
  418.             DX:AX = signed long integer number to convert
  419.                     (high word in DX)
  420. Returns:    converted number in float4 IEEE format at DS:[BX]
  421. Uses:       nothing; all registers and flags are saved
  422. Example:
  423.  
  424. include asm.inc
  425.  
  426. extrn   i4tof4:proc
  427.  
  428. .data
  429. float4  dd ?                          ; initial number undefined
  430. longint dd -123456789
  431.  
  432. .code
  433. ; program fragment assumes DS:@data
  434.         .
  435.         .
  436.         .
  437.         mov    ax,word ptr longint    ; low word of signed long integer
  438.         mov    dx,word ptr longint+2  ; high word of signed long integer
  439.         lea    bx,float4              ; point to buffer for converted number
  440.         call   i4tof4
  441.  
  442.  
  443.  
  444. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  445.  
  446. INVF4:      calculate the inverse of a float4 number
  447. Source:     invf4.asm
  448.  
  449. 80x87 not required
  450.  
  451. Call with:  DS:[SI] = address of float4 number
  452. Returns:    DS:[SI] = address of 1/number
  453.             previous number is overwritten
  454. Uses:       nothing
  455. Example:
  456.  
  457. include asm.inc
  458.  
  459. extrn   invf4:proc
  460.  
  461. .code
  462. ; program fragment assumes DS:@data
  463.         .
  464.         .
  465.         .
  466.         lea   si,float4          ; point to float4 number
  467.         call  invf4              ; original number replaced with inverse
  468.  
  469.  
  470.  
  471. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  472.  
  473. MAXF4, MAXF4b: find maximum number in single-precision real-number array
  474. Source:        small & medium models: maxf4.asm
  475.                huge model: maxf4.asm (lowDS2hi.asm)
  476.  
  477. MINF4, MINF4b: find minimum number in single-precision real-number array
  478. Source:        small & medium models: minf4.asm
  479.                huge model: minf4.asm (lowDS2hi.asm)
  480.  
  481. 80x87 not required
  482.  
  483. Call with:  ES:[DI] pointing to array element at start of search
  484.             CX = number of array elements to search
  485.             For maxf4b or minf4b, call with BX = byte increment between
  486.             array elements.  Maxf4 and minf4 assume byte increment = 4.
  487. Returns:    AX = array element number with maximum or minimum value
  488.             note that the offset of that number is DI + (AX shl 2).
  489.             With maxf4b and minf4b, the offset of the number is
  490.             DI + (AX * BX).
  491.             AX = -1 if maxf4 was called with CX = 0
  492. Uses:       AX
  493. Example:
  494.  
  495. include asm.inc
  496.  
  497. extrn  maxf4:proc
  498.  
  499. .data
  500. floatdata   dd 1500 dup(0)
  501.  
  502. .code
  503. ; program fragment assumes DS:@data
  504. ; program provides values for the array
  505.        .
  506.        .
  507.        .
  508.        push   ds
  509.        pop    es
  510.        assume es:@data
  511.        lea    di,floatdata      ; ES:[DI] points to the data array
  512.        mov    cx,1500           ; search entire array
  513.        call   maxf4             ; returns with AX = array element
  514.  
  515.  
  516.  
  517. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  518.  
  519. MAXF8, MAXF8b: find maximum value in double-precision real-number array
  520. Source:        maxf8.asm
  521.  
  522. MINF8, MINF8b: find minimum value in double-precision real-number array
  523. Source:        minf8.asm
  524.  
  525. 80x87 not required
  526.  
  527. Call with:  ES:[DI] pointing to array element at start of search
  528.             CX = number of array elements to search
  529.             For maxf8b or minf8b, call with BX = byte increment between
  530.             array elements.  Maxf8 and minf8 assume byte increment = 8.
  531. Returns:    AX = array element number with maximum or minimum value
  532.             note that the offset of that number is DI + (AX shl 3)
  533.             With maxf8b and minf8b, the offset of the number is
  534.             DI + (AX * BX).
  535.             AX = -1 if maxf8 was called with CX = 0
  536. Uses:       AX
  537. Example:
  538.  
  539. include asm.inc
  540.  
  541. extrn  maxf8:proc
  542.  
  543. .data
  544. floatdata   dq 1500 dup(0)
  545.  
  546. .code
  547. ; program fragment assumes DS:@data
  548. ; program provides values for the array
  549.        .
  550.        .
  551.        .
  552.        push   ds
  553.        pop    es
  554.        assume es:@data
  555.        lea    di,floatdata      ; ES:[DI] points to the data array
  556.        mov    cx,1500           ; search entire array
  557.        call   maxf8             ; returns with AX = array element
  558.        mov    cl,3
  559.        shl    ax,cl
  560.        add    di,ax             ; ES:[DI] points to maximum value
  561.  
  562.  
  563.  
  564. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  565.  
  566. MULF4:      multiplies two float4 numbers
  567. Source:     mulf4.asm
  568.  
  569. 80x87 not required
  570.  
  571. Call with:  DS:[SI] pointing to real0, ES:[DI] pointing to real1
  572. Returns:    if CF = 0, no error; product replaces real0 at DS:[SI]
  573.             if CF = 1, the product is either zero or infinity (real0 is lost)
  574. Uses:       CF; all other flags and registers are saved
  575. Example:
  576.  
  577. include asm.inc
  578.  
  579. extrn  mulf4:proc
  580.  
  581. .data
  582. real0    dd 1.234
  583. real1    dd 0.5
  584.  
  585. .code
  586. ; program fragment assumes DS:@data
  587.          .
  588.          .
  589.          .
  590.          push   ds
  591.          pop    es
  592.          assume es:@data
  593.          lea    si,real0
  594.          lea    di,real1
  595.          call   mulf4
  596.  
  597.  
  598. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  599.  
  600. MULF4TEN:   multiply a float4 number by 10
  601. Source:     mulf4ten.asm (mulf4.asm)
  602.  
  603. 80x87 not required
  604.  
  605. Call with:  DS:[SI] pointing to float4 number
  606.             MulF4Ten is front-end code for MulF4, which saves ES and DI,
  607.             points ES:[DI] to f4 data equalling 10.0, calls MulF4, then
  608.             restores ES and DI.
  609. Returns:    if CF = 0, float4 number at DS:[SI] multiplied by 10.0
  610.             if CF = 1, the product is either 0 or infinity
  611. Uses:       CF; all other flags and registers are saved
  612. Example:
  613.  
  614. include asm.inc
  615.  
  616. extrn  mulf4ten:proc
  617.  
  618. .data
  619. real0    dd 1.234
  620.  
  621. .code
  622. ; program fragment assumes DS:@data
  623.          .
  624.          .
  625.          .
  626.          lea    si,real0
  627.          call   mulf4ten
  628.  
  629.  
  630. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  631.  
  632. MULF8:      multiplies two float8 numbers
  633. Source:     mulf8.asm (mpmul.asm)
  634.  
  635. 80x87 not required
  636.  
  637. Call with:  DS:[SI] pointing to real0, ES:[DI] pointing to real1
  638. Returns:    if CF = 0, no error; product replaces real0 at DS:[SI]
  639.             if CF = 1, the product is either zero or infinity (real0 is lost)
  640. Uses:       CF; all other flags and registers are saved
  641. Example:
  642.  
  643. include asm.inc
  644.  
  645. extrn  mulf8:proc
  646.  
  647. .data
  648. real0    dq 1.2347349
  649. real1    dq 0.5
  650.  
  651. .code
  652. ; program fragment assumes DS:@data
  653.          .
  654.          .
  655.          .
  656.          push   ds
  657.          pop    es
  658.          assume es:@data
  659.          lea    si,real0
  660.          lea    di,real1
  661.          call   mulf8
  662.  
  663.  
  664. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  665.  
  666. MULF8TEN:   multiply a float8 number by 10
  667. Source:     mulf8ten.asm (mulf8.asm, mpmul.asm)
  668.  
  669. 80x87 not required
  670.  
  671. Call with:  DS:[SI] pointing to float8 number
  672.             MulF8Ten is front-end code for MulF8, which saves ES and DI,
  673.             points ES:[DI] to f8 data equalling 10.0, calls MulF8, then
  674.             restores ES and DI.
  675. Returns:    if CF = 0, float8 number at DS:[SI] multiplied by 10.0
  676.             if CF = 1, the product is either 0 or infinity
  677. Uses:       CF; all other flags and registers are saved
  678. Example:
  679.  
  680. include asm.inc
  681.  
  682. extrn  mulf8ten:proc
  683.  
  684. .data
  685. real0    dq 1.234
  686.  
  687. .code
  688. ; program fragment assumes DS:@data
  689.          .
  690.          .
  691.          .
  692.          lea    si,real0
  693.          call   mulf8ten
  694.  
  695.  
  696. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  697.  
  698. SCALEF4:    scale a float4 number by an integer power of 2
  699. Source:     scalef4.asm
  700.  
  701. 80x87 not required
  702.  
  703. Call with:  DS:[SI] pointing to the float4 data
  704.             AL = scale factor (may be positive or negative)
  705. Returns:    CF = 0 if success: float4 number was properly scaled
  706.             CF = 1 if error: resulting float4 number would have overflowed
  707.                    float4 number unchanged in this case
  708. Uses:       CF; all other flags and all registers saved
  709. Example:
  710.  
  711. include asm.inc
  712.  
  713. .code
  714. ; program fragment assumes DS:@data
  715.         .
  716.         .
  717.         .
  718.         lea   si,float4data
  719.         mov   al,3             ; scale by (2^3) effectively multiplies by 8
  720.         call  scalef4
  721.         jc    oops             ; take remedial action if error
  722.  
  723.  
  724. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  725.  
  726. SCALEF8:    scale a float8 number by an integer power of 2
  727. Source:     scalef8.asm
  728.  
  729. 80x87 not required
  730.  
  731. Call with:  DS:[SI] pointing to the float8 data
  732.             AL = scale factor (may be positive or negative)
  733. Returns:    CF = 0 if success: float8 number was properly scaled
  734.             CF = 1 if error: resulting float8 number would have overflowed
  735.                    float8 number unchanged in this case
  736. Uses:       CF; all other flags and all registers saved
  737. Example:
  738.  
  739. include asm.inc
  740.  
  741. .code
  742. ; program fragment assumes DS:@data
  743.         .
  744.         .
  745.         .
  746.         lea   si,float8data
  747.         mov   al,3             ; scale by (2^3) effectively multiplies by 8
  748.         call  scalef8
  749.         jc    oops             ; take remedial action if error
  750.  
  751.  
  752.  
  753. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  754.  
  755. SORTF4HI:    sort an array of single-precision real numbers, highest first
  756. Source:      sortf4hi.asm
  757.  
  758. SORTF4LO:    sort an array of single-precision real numbers, lowest first
  759. Source:      sortf4lo.asm
  760.  
  761. 80x87 not required
  762.  
  763. Call with:  ES:[DI] pointing to the first of the array elements to be
  764.             sorted, CX = number of array elements
  765. Returns:    nothing
  766. Uses:       nothing; all registers and flags are saved
  767. Example:
  768.  
  769. include asm.inc
  770.  
  771. extrn  sortf4hi:proc
  772.  
  773. .data
  774. floatdata   dd 1500 dup(0)
  775.  
  776. .code
  777. ; program fragment assumes DS:@data
  778. ; program provides values for the array
  779.         .
  780.         .
  781.         push    ds
  782.         pop     es
  783.         assume  es:@data
  784.         lea     di,floatdata
  785.         mov     cx,1500           ; sort entire array
  786.         call    sortf4hi          ; highest number first
  787.  
  788.  
  789.  
  790. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  791.  
  792. SORTF8HI:    sort an array of double-precision real numbers, highest first
  793. Source:      sortf8hi.asm
  794.  
  795. SORTF8LO:    sort an array of double-precision real numbers, lowest first
  796. Source:      sortf8lo.asm
  797.  
  798. 80x87 not required
  799.  
  800. Call with:  ES:[DI] pointing to the first of the array elements to be
  801.             sorted, CX = number of array elements
  802. Returns:    nothing
  803. Uses:       nothing; all registers and flags are saved
  804. Example:
  805.  
  806. include asm.inc
  807.  
  808. extrn  sortf8hi:proc
  809.  
  810. .data
  811. floatdata   dq 1500 dup(0)
  812.  
  813. .code
  814. ; program fragment assumes DS:@data
  815. ; program provides values for the array
  816.         .
  817.         .
  818.         push    ds
  819.         pop     es
  820.         assume  es:@data
  821.         lea     di,floatdata
  822.         mov     cx,1500           ; sort entire array
  823.         call    sortf8hi          ; highest number first
  824.  
  825.  
  826.  
  827. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  828.  
  829. SUBF4:       subtract one float4 number from another
  830. Source:      subf4.asm (addf4.asm)
  831.  
  832. SUBF8:       subtract one float8 number from another
  833. Source:      subf8.asm (addf8.asm)
  834.  
  835. 80x87 not required
  836.  
  837. Call with:   DS:[SI] pointing to real0
  838.              ES:[DI] pointing to real1
  839.              the number at ES:[DI] is subtracted from the number at DS:[SI]
  840.              with the result replacing the number at DS:[SI]
  841. Returns:     if CF = 0, DS:[SI] points to real0 - real1
  842.              if CF = 1, the operation would result in an overflow;
  843.                 neither number is changed
  844. Uses:        nothing; all registers and flags are saved
  845. Example:
  846.  
  847. include asm.inc
  848.  
  849. extrn subf4:proc
  850.  
  851. .data
  852. real0   dd 123.456
  853. real1   dd -67.4
  854.  
  855. .code
  856. ; program fragment assumes DS:@data
  857.          .
  858.          .
  859.          .
  860.         push    ds
  861.         pop     es           ; ES = DS
  862.         assume  es:@data
  863.         lea     si,real0
  864.         lea     di,real1
  865.         call    subf4
  866.